package com.biz.primus.ms.oms.service.core;

import com.biz.primus.common.utils.Copier;
import com.biz.primus.model.oms.enums.OrderDeliveryState;
import com.biz.primus.model.oms.vo.ChangeShippingInfoRequest;
import com.biz.primus.model.oms.vo.FillExpressInfoRequest;
import com.biz.primus.model.oms.vo.UserOrderOperationRequest;
import com.biz.primus.model.oms.vo.OrderCloseRequest;
import com.biz.primus.ms.oms.dao.po.OmsOrder;
import com.biz.primus.ms.oms.vo.OmsOrderResource;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

/**
 * 状态服务: 提供订单状态流转的功能
 *
 *
 * 订单状态:
 *      新订单 - 已分单 - 已打单 - 已出库 - 已完成
 * 支付状态:
 *      货到付款 - 已支付
// * del - 评价状态:
// * del -      订单未完成 - 待评价 - 已评价
 *
 * 取消标识
 *      NONE - CANCEL - CLOSED
 *
 * 售后标识
 *
 * 配送方式:
 *      自提/自配送/第三方物流
 * 配送状态:
 *      订单未出库 - 待自提/(待发货 - 配送中) - 已签收/拒收/部分签收
 *
 *
 *
 * @author yanweijin
 * @date 2017/10/18
 */
@Transactional(rollbackFor = Exception.class)
public interface OrderStateService {


//	/**
//	 * 订单状态变更
//	 * @param req
//	 */
//	void stateChange(OrderStateChangeRequest req);


	OmsOrder findOrder(OmsOrderResource req);

	/**
	 *
	 * 重置订单状态为begin
	 *
	 * @param req
	 * @param sendMessage 如果为true, 则触发订单流消息
	 */
	void backToBegin(OrderStateChangeRequest req, boolean sendMessage);

	/**
	 * 订单分单
	 *  0. 修改订单状态
	 *  1. 修改订单指向门店
	 *  2. 通知指定门店有新订单
	 *
	 * @param req
	 */
	void allocateOrder(AllocationStateRequestVo req);

	/**
	 * 打印订单小票
	 *  0. 修改订单状态
	 *
	 * @param req
	 */
	void printOrder(OrderStateChangeRequest req);


	/**
	 * 订单出库
	 *  0. 修改订单状态
	 *  1. 根据配送方式,修改出库状态
	 *  2. 如果是自配送,需要通知配送app
	 *
	 * @param req
	 */
	void outbound(OrderStateChangeRequest req);

	/**
	 * 完成订单, 填入签收状态
	 *
	 * @param req
	 */
	void finishOrder(OrderStateChangeRequest req, OrderDeliveryState deliveryState);


	/**
	 * 发快递的订单,填写快递信息:
	 *  1. 更新快递信息
	 *  2. 如果配送状态在distributing之前,更新到distributing
	 *
	 * @param req
	 */
	void fillExpressInfo(FillExpressInfoRequest req);


	//现金转支付

	void  cashTransferPayment(String orderCode);

	/**
	 * 修改配送方式
	 *
	 * 1. 检查订单状态:
	 *      source=cs:      state=allocated, printed, orderOutbound;
	 *      source=depot:   state=allocated, printed,
	 * 2. 检查更新的数据(判断配送方式是否和原本一致,如果不一致,需要做修改配送方式相应动作)
	 * 3. 生成自提码/通知配送app...
	 * 4. 记录日志
	 *
	 * @param req
	 */
	void changeConsigneeInfo(ChangeShippingInfoRequest req);

	/**
	 * 用户取消订单:
	 *  只能在 printed 前取消
	 *  如果用户已经支付,则生退款单
	 * @param req
	 */
	void cancelOrder(UserOrderOperationRequest req);

	/**
	 * 后台关闭订单:
	 *  只能在 outbound 前取消
	 *  如果用户已经支付,则生成退款单
	 * @param req
	 */
	void closeOrder(OrderCloseRequest req);





	@Data
	@Builder
	@ApiModel("订单状态变更请求")
	@NoArgsConstructor
	@AllArgsConstructor
	class OrderStateChangeRequest implements OmsOrderResource{
		/**订单id/订单编号/订单实体必须提供一个*/
		@ApiModelProperty("订单id,订单id/订单编号/订单实体必须提供一个")
		Long orderId;
		/**订单id/订单编号/订单实体必须提供一个*/
		@ApiModelProperty("订单实体,订单id/订单编号/订单实体必须提供一个")
		OmsOrder order;
		/**订单id/订单编号/订单实体必须提供一个*/
		@ApiModelProperty("订单编号,订单id/订单编号/订单实体必须提供一个")
		String code;
		/**操作人*/
		@ApiModelProperty("操作人")
		String operator;

		/**门店编号*/
		@ApiModelProperty("门店编号,如果填写了这个参数,操作时会检查订单是否属于门店")
		String depot;

		@ApiModelProperty("操作备注")
		String remark;
	}

	@Data
	@ApiModel("分单请求")
	class AllocationStateRequestVo extends OrderStateChangeRequest{
		@ApiModelProperty("分配的目标门店")
		String targetDepotCode;
		@ApiModelProperty("调拨标识,为true时,门店不能主动申请改派")
		boolean needDispatching;

		public AllocationStateRequestVo(OrderStateChangeRequest req, String targetDepotCode, boolean needDispatching){
			Copier.from(req).to(this);
			this.targetDepotCode = targetDepotCode;
			this.needDispatching = needDispatching;
		}

	}

}
